Security applications have a different sense of ``random'' from the statistical definitions that apply to pseudo-random number generators used for (e.g.) Monte Carlo simulation. In a security setting, the heart of the matter is unguessability. I've got a script I use for generating passwords, and that sort of thing. It shoots for unguessability. I append it after my .sig. -Bennett bet@sbi.com #!/usr/local/bin/perl ($progname=$0)=~s#.*/##; $syntax="syntax: $progname [-n] [len [printable|all|hex|HEX]]\n"; require 'getopts.pl'; &Getopts('n') || die $syntax; defined($max = shift) || ($max = 8); defined($alphabet = shift) || ($alphabet = 'printable'); ($#ARGV == -1) || die $syntax; domain: { $_ = $alphabet; /^printable$/ && do { $chars = pack("C*", (32 .. 126)); last domain; }; /^all$/ && do { $chars = pack("C*", ( 0 .. 255)); last domain; }; /^hex$/ && do { $chars = "0123456789abcdef"; last domain; }; /^HEX$/ && do { $chars = "0123456789ABCDEF"; last domain; }; die $syntax; }; @chars = split('', $chars); @randstring = split('', &randbits($max)); foreach $i (@randstring) { print $chars[ord($i) % $#chars]; } print "\n" unless $opt_n; exit 0; sub randbits { local($nbytes) = @_; local(*_, $noise, $buf, $limit, $discard, $newlen); # Here's the big non-portability. This command works really well on # Sun workstations running SunOS; on other platforms, root around for # commands that report lots of detailed OS internals state, plus a # compressor or other program to smear the bits about. $noise = '(ps -agxlww;free;pstat -afipSsT)2>/dev/null|compress'; # Run the noise command; in case it croaks, slap on whatever other state we # can conveniently (portably) find. $buf = `$noise` . $$ . getppid() . time . join('', %ENV); # Gotta have enough bits for at least one good fold. $limit = int(length($buf)/2); die "Insufficient random state; try less than $limit\n" if $nbytes > $limit; # Get Perl to treat ^ as bit-string op $discard = vec($buf, 0, 8); # Now fold the noise down by repeated xor, halving the buffer until it's but # little bigger than xauth(1) wants. while (length($buf) >= $nbytes*2) { $newlen = int((length($buf) + 1) / 2); $buf = (substr($buf, 0, $newlen) ^ substr($buf, $newlen, $newlen)); } # Final fold may turn in some nulls, but fits it exactly to $nbytes without # discarding any bits. substr($buf, 0, $nbytes) ^ substr($buf, $nbytes, $nbytes); }